﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Birkelund.QueryStrings.Tokens;
using System.Web;

namespace Birkelund.QueryStrings.Test.IntegrationTests
{
    public class CustomizedTokenTest
    {
        [Test]
        public void SupportForNewTokenType()
        {
            IQueryStringToken<Point> a = new PointToken("a");
            Point p = new Point(19, 20);
            string initialUrl = "http://localhost/test.aspx";

            IUriWriter writer = UriWriter.CreateEmptyFromUri(initialUrl);
            writer.SetToken(a, p);

            string generatedUrlAsString = writer.GenerateQueryAsString();

            Assert.AreEqual("http://localhost/test.aspx?a=19%2c20", generatedUrlAsString);
            Assert.AreEqual(p, a.ReadValue(new Uri(generatedUrlAsString)));
        }

        private class Point
        {
            public int X { get; private set; }
            public int Y { get; private set; }

            public Point(int x, int y)
            {
                this.X = x;
                this.Y = y;
            }

            public override bool Equals(object obj)
            {
                //ignore guarding

                return
                    ((Point)obj).X == this.X &&
                    ((Point)obj).Y == this.Y;
            }

            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
        }

        private class PointToken : QueryStringTokenBase<Point>
        {
            public PointToken(string keyName)
                : base(keyName)
            {
            }

            protected override string OnRenderTokenValue(Point value)
            {
                if (value == null)
                    return null;

                return string.Format("{0},{1}", value.X, value.Y);
            }

            protected override Point OnParseFromString(string attemptedValue)
            {
                if (string.IsNullOrEmpty(attemptedValue))
                {
                    return null;
                }
                else
                {
                    int x;
                    int y;
                    string[] values = attemptedValue.Split(',');
                    if (values.Length == 2 && int.TryParse(values[0], out x) && int.TryParse(values[1], out y))
                    {
                        return new Point(x, y);
                    }
                    else throw new InvalidCastException("Unable to parse to integers");
                }
            }
        }
    }
}
